#include "ModuleEMD.h"

void ModuleEMD::init(QCVModuleHandlerInterface * parent)
{
	this->parent=parent;
	parent->setAutoProcess(false);
	emd.create(1,1);

	win=new QWidget();
  layout=new QVBoxLayout(win);
	le_EMD=new QLineEdit(win);
	pb_costMatStd=new QPushButton(trUtf8("Matrice des coûts"),win);
	pb_adjMat=new QPushButton(trUtf8("Matrice des adjacences"),win);

	cb_useConnexGraphDistance=new QCheckBox(trUtf8("Distance de connexité"),win);
	layout->addWidget(cb_useConnexGraphDistance);
	layout->addWidget(le_EMD);
	layout->addWidget(pb_costMatStd);
	layout->addWidget(pb_adjMat);

	connect(cb_useConnexGraphDistance,SIGNAL(stateChanged(int)),this,SLOT(s_use_graph(int)));
	connect(pb_costMatStd,SIGNAL(clicked()),this,SLOT(s_costMatStd()));
	connect(pb_adjMat,SIGNAL(clicked()),this,SLOT(s_adjMatStd()));
	
}
////////////////////////////////////////////////////////////////////////////////
void ModuleEMD::free()
{
	delete win;
}
////////////////////////////////////////////////////////////////////////////////
cv::Mat & ModuleEMD::process()
{
  //n'est jamais executée
	std::cout<<"Erreur ModuleEMD : La fonction process ne doit pas etre executée\n";
}
////////////////////////////////////////////////////////////////////////////////
void ModuleEMD::setInput(int n,const cv::Mat & m)
{
	if(n==0)
	{	
		hist1=m.clone();
	}
	if(n==1)
	{	
		hist2=m.clone();
	}
	if(n==2)
	{	
		adjMat=m.clone();		
		QCVGraph graph;
		graph.read(adjMat);
		graph.getCostMat(costMat);
	}

	//seul la premiere entrée déclanche le calcul
	if(n==0)
	{
		if(cb_useConnexGraphDistance->isChecked())
		{
			if(!hist1.empty() && !hist2.empty() && !costMat.empty())
			{
				if(hist1.rows!=hist2.rows)
				{
					std::cout<<"Erreur ModuleEMD: Les histogrammes doivent avoir la meme dimension\n";
				}
				else
				{
					CvMat oldFormatHist1=hist1;
					CvMat oldFormatHist2=hist2;
					CvMat oldFormatCostMat=costMat;			
				
					emd(0,0)=cvCalcEMD2(&oldFormatHist1,&oldFormatHist2,CV_DIST_USER,NULL,&oldFormatCostMat);

					le_EMD->setText(tr("EMD=")+QString::number(emd(0,0)));
			
					parent->forceOutput(emd);
				}
			}
		}
		else
		{
			if(!hist1.empty() && !hist2.empty())
			{
				if(hist1.rows!=hist2.rows)
				{
					std::cout<<"Erreur ModuleEMD: Les histogrammes doivent avoir la meme dimension\n";
				}
				else
				{
					costMat.create(hist1.rows,hist1.rows);
					for(int i=0;i<hist1.rows;i++)
					{
						for(int j=0;j<hist1.rows;j++)
						{
							costMat(i,j)=abs(i-j);
						}
					}

					CvMat oldFormatHist1=hist1;
					CvMat oldFormatHist2=hist2;
					CvMat oldFormatCostMat=costMat;
			
			
					emd(0,0)=cvCalcEMD2(&oldFormatHist1 , &oldFormatHist2, CV_DIST_USER, NULL, &oldFormatCostMat);

					le_EMD->setText(tr("EMD=")+QString::number(emd(0,0)));
			
					parent->forceOutput(emd);
				}
			}
		}
	}
}
////////////////////////////////////////////////////////////////////////////////
QWidget* ModuleEMD::widget()
{
	return win;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleEMD::getName()
{
	return tr("Distance EMD");
}
////////////////////////////////////////////////////////////////////////////////
int ModuleEMD::nbInputs()
{
	return 2+cb_useConnexGraphDistance->isChecked();
}
////////////////////////////////////////////////////////////////////////////////
bool ModuleEMD::setParams(QString params)
{
	QStringList list_params=params.split(";");
		
	if(list_params.size()==1)
	{
		cb_useConnexGraphDistance->setChecked(list_params[0].toInt());
		return true;
	}
	else
	{
		return false;
	}	
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleEMD::getParams()
{
	return QString::number(cb_useConnexGraphDistance->isChecked());
}
////////////////////////////////////////////////////////////////////////////////
QCVModuleInterface * ModuleEMD::clone()
{
		ModuleEMD * selfcopy=new ModuleEMD;
		return selfcopy;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleEMD::help(int id)
{
	if(id==-2)
	{
		return tr("Calcule la distance EMD (Earth Mover Distance)");
	}
	else if(id==-1)
	{
		return tr("nombre");
	}
	else if(id==0)
	{
		return tr("histogramme");
	}
	else if(id==1)
	{
		return tr("histogramme");
	}
	else if(id==2)
	{
		return tr("graph");
	}
	else
	{
		return tr("erreur");
	}
}
////////////////////////////////////////////////////////////////////////////////
void ModuleEMD::s_use_graph(int state)
{

}
/////////////////////////////////////////////////////////////////	///////////////
void ModuleEMD::s_costMatStd()
{
	if(!costMat.empty())
	{
		std::cout<<"\ncostMat=\n"<<costMat<<"\n";
	}
	else
	{
		std::cout<<"\ncostMat=NULL\n";
	}
}
void ModuleEMD::s_adjMatStd()
{
	if(!adjMat.empty())
	{
		std::cout<<"\nadjMat=\n"<<adjMat<<"\n";
	}
	else
	{
		std::cout<<"\nMatrice des couts=NULL\n";
	}
}

////////////////////////////////////////////////////////////////////////////////
Q_EXPORT_PLUGIN2(ModuleEMD_plugin,ModuleEMD);  
